package top.kaoshanji.p3ch11b;

import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import top.kaoshanji.u1constant.FileConstant;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Phaser;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 代码清单-p3ch11b-372页a：Phaser类的使用示例
 * author kaoshanji
 * ^_^
 * create time 2025/2/5 15:50
 */
public class WebPageImageDownloader {

    private static final Logger logger = LogManager.getLogger(WebPageImageDownloader.class);

    public static void main(String[] args) throws IOException {
        logger.info("...代码清单-p3ch11b-372页a：Phaser类的使用示例...");

        URL url = new URL("http://www.baidu.com");
        String rootPath = FileConstant.LOCAL_ROOT_PATH.concat("p3ch11b372页a\\");

        WebPageImageDownloader downloader = new WebPageImageDownloader();
        downloader.download(url, Paths.get(rootPath), null);

    }

    private final Phaser phaser = new Phaser(1);
    private final Pattern imageUrlPattern = Pattern.compile("src=['\"]?(.*?(\\.jpg|\\.gif|\\.png))['\"]?[\\s>]+", Pattern.CASE_INSENSITIVE);

    // 主要逻辑在这个方法里面
    // 但是，里面一些辅助逻辑就单独定义方法
    public void download(URL url, Path path, Charset charset) throws IOException {

        if (charset == null) {
            charset = StandardCharsets.UTF_8;
        }

        String content = getContent(url, charset);
        List<URL> imageUrls = extractImageUrls(content);
        for (final URL imageUrl: imageUrls) {
            phaser.register();
            new Thread() {
                @Override
                public void run() {
                    phaser.arriveAndAwaitAdvance();

                    try {
                        InputStream is = imageUrl.openStream();
                        Files.copy(is, getSavePath(path, imageUrl), StandardCopyOption.REPLACE_EXISTING);
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        phaser.arriveAndDeregister();
                    }
                }
            }.start();
        }

        phaser.arriveAndAwaitAdvance();
        phaser.arriveAndAwaitAdvance();
        phaser.arriveAndDeregister();
    }

    private String getContent(URL url, Charset charset) throws IOException {
        InputStream is = url.openStream();
        return IOUtils.toString(new InputStreamReader(is, charset));
    }

    private List<URL> extractImageUrls(String content) {
        List<URL> result = new ArrayList<>();
        Matcher matcher = imageUrlPattern.matcher(content);
        while (matcher.find()) {
            try {
                result.add(new URL(matcher.group(1)));
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            }
        }
        return result;
    }

    private Path getSavePath(Path parent, URL url) {
        String urlString = url.toString();
        int index = urlString.lastIndexOf("/");
        String fileName = urlString.substring(index + 1);
        return parent.resolve(fileName);
    }

}
